﻿using System;
using jQueryApi;
using System.Html;

namespace Quicklight.Web.Razor {

   /// <summary>
   /// This class binds to an event of an element. This class simply locates the element identified by the element locator and calls an abstract method Bind
   /// to do the actual binding. Extend this class to bind something to the event
   /// </summary>
   public abstract class EventBinder : Binder {
      protected string eventName;

      /// <summary>
      /// Constructs an EventBinder that will bind to the specified event
      /// </summary>
      /// <param name="eventName">Event to bind to</param>
      public EventBinder(string eventName) {
         this.eventName = eventName;
      }

      /// <summary>
      /// Creates and returns an element locator. The element locator is an attribute set equal to a value. The attribute is bind-eventname and the value is the key provided
      /// </summary>
      /// <param name="key">Unique key for this binder instance</param>
      /// <returns>The element locator that will be used by the Bind method to locate the element</returns>
      public override string GetElementLocator(string key) {
         return String.Format(@"bind-{0}=""{1}""", eventName, key);
      }

      /// <summary>
      /// This method locates the element using the element locator, ensures that it has an id, then calls the abstract Bind method to bind the element. It then removes the element locator
      /// </summary>
      /// <param name="key">Unique key for this binder instance</param>
      public override void Bind(string key) {
         string elementLocator = GetElementLocator(key);
         elementLocator = elementLocator.Replace("(", @"\(").Replace(":", @"\:").Replace("|", @"\|").Replace(@"\", @"\\").Replace(".", @"\.").Replace(")", @"\)");
         jQueryObject jQueryObject = jQuery.Select(String.Format("[{0}]", elementLocator));
         if (jQueryObject == null)
            return;

         string id = jQueryObject.GetAttribute("id");
         if (String.IsNullOrEmpty(id)) {
            id = key;
            jQueryObject.Attribute("id", id);
         }

         Element element = Document.Instance.GetElementById(id);
         Bind(element);

         jQueryObject.RemoveAttr(String.Format("bind-{0}", eventName));
      }

      /// <summary>
      /// Abstract Bind method that does the actual binding
      /// </summary>
      /// <param name="element">Element to bind to</param>
      protected abstract void Bind(Element element);
   }
}
